home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / misc / AmigaSDLsrc.lha / amisrc / SDL_mouse.c < prev    next >
C/C++ Source or Header  |  2001-04-29  |  6KB  |  248 lines

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. #ifdef SAVE_RCSID
  24. static char rcsid =
  25.  "@(#) $Id: SDL_mouse.c,v 1.3.2.10 2001/02/10 07:20:04 hercules Exp $";
  26. #endif
  27.  
  28. /* General mouse handling code for SDL */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33.  
  34. #include "SDL_events.h"
  35. #include "SDL_events_c.h"
  36. #include "SDL_cursor_c.h"
  37. #include "SDL_sysvideo.h"
  38.  
  39.  
  40. /* These are static for our mouse handling code */
  41. static Sint16 SDL_MouseX = 0;
  42. static Sint16 SDL_MouseY = 0;
  43. static Sint16 SDL_DeltaX = 0;
  44. static Sint16 SDL_DeltaY = 0;
  45. static Uint8  SDL_ButtonState = 0;
  46.  
  47.  
  48. /* Public functions */
  49. int SDL_MouseInit(void)
  50. {
  51.     /* The mouse is at (0,0) */
  52.     SDL_MouseX = 0;
  53.     SDL_MouseY = 0;
  54.     SDL_DeltaX = 0;
  55.     SDL_DeltaY = 0;
  56.     SDL_ButtonState = 0;
  57.  
  58.     /* That's it! */
  59.     return(0);
  60. }
  61.  
  62. Uint8 SDL_GetMouseState (int *x, int *y)
  63. {
  64.     if ( x )
  65.         *x = SDL_MouseX;
  66.     if ( y )
  67.         *y = SDL_MouseY;
  68.     return(SDL_ButtonState);
  69. }
  70.  
  71. Uint8 SDL_GetRelativeMouseState (int *x, int *y)
  72. {
  73.     if ( x )
  74.         *x = SDL_DeltaX;
  75.     if ( y )
  76.         *y = SDL_DeltaY;
  77.     SDL_DeltaX = 0;
  78.     SDL_DeltaY = 0;
  79.     return(SDL_ButtonState);
  80. }
  81.  
  82. static void ClipOffset(Sint16 *x, Sint16 *y)
  83. {
  84.     /* This clips absolute mouse coordinates when the apparent
  85.        display surface is smaller than the real display surface.
  86.      */
  87.     if ( SDL_VideoSurface->offset ) {
  88.         *y -= SDL_VideoSurface->offset/SDL_VideoSurface->pitch;
  89.         *x -= (SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/
  90.                 SDL_VideoSurface->format->BytesPerPixel;
  91.     }
  92. }
  93.  
  94. /* These are global for SDL_eventloop.c */
  95. int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y)
  96. {
  97.     int posted;
  98.     Uint16 X, Y;
  99.     Sint16 Xrel;
  100.     Sint16 Yrel;
  101.  
  102.     /* Don't handle mouse motion if there's no cursor surface */
  103.     if ( SDL_VideoSurface == NULL ) {
  104.         return(0);
  105.     }
  106.  
  107.     /* Default buttonstate is the current one */
  108.     if ( ! buttonstate ) {
  109.         buttonstate = SDL_ButtonState;
  110.     }
  111.  
  112.     Xrel = x;
  113.     Yrel = y;
  114.     if ( relative ) {
  115.         /* Push the cursor around */
  116.         x = (SDL_MouseX+x);
  117.         y = (SDL_MouseY+y);
  118.     } else {
  119.         /* Do we need to clip {x,y} ? */
  120.         ClipOffset(&x, &y);
  121.     }
  122.  
  123.     /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
  124.     if ( x < 0 )
  125.         X = 0;
  126.     else
  127.     if ( x >= SDL_VideoSurface->w )
  128.         X = SDL_VideoSurface->w-1;
  129.     else
  130.         X = (Uint16)x;
  131.  
  132.     if ( y < 0 )
  133.         Y = 0;
  134.     else
  135.     if ( y >= SDL_VideoSurface->h )
  136.         Y = SDL_VideoSurface->h-1;
  137.     else
  138.         Y = (Uint16)y;
  139.  
  140.     /* If not relative mode, generate relative motion from clamped X/Y.
  141.        This prevents lots of extraneous large delta relative motion when
  142.        the screen is windowed mode and the mouse is outside the window.
  143.     */
  144.     if ( ! relative ) {
  145.         Xrel = X-SDL_MouseX;
  146.         Yrel = Y-SDL_MouseY;
  147.     }
  148.  
  149.     /* Update internal mouse state */
  150.     SDL_ButtonState = buttonstate;
  151.     SDL_MouseX = X;
  152.     SDL_MouseY = Y;
  153.     SDL_DeltaX += Xrel;
  154.     SDL_DeltaY += Yrel;
  155.     SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
  156.  
  157.     /* Post the event, if desired */
  158.     posted = 0;
  159.     if ( SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE ) {
  160.         SDL_Event event;
  161.         memset(&event, 0, sizeof(event));
  162.         event.type = SDL_MOUSEMOTION;
  163.         event.motion.state = buttonstate;
  164.         event.motion.x = X;
  165.         event.motion.y = Y;
  166.         event.motion.xrel = Xrel;
  167.         event.motion.yrel = Yrel;
  168.         if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
  169.             posted = 1;
  170.             SDL_PushEvent(&event);
  171.         }
  172.     }
  173.     return(posted);
  174. }
  175.  
  176. int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y)
  177. {
  178.     SDL_Event event;
  179.     int posted;
  180.     int move_mouse;
  181.     Uint8 buttonstate;
  182.  
  183.     memset(&event, 0, sizeof(event));
  184.  
  185.     /* Check parameters */
  186.     if ( x || y ) {
  187.         ClipOffset(&x, &y);
  188.         move_mouse = 1;
  189.         /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
  190.         if ( x < 0 )
  191.             x = 0;
  192.         else
  193.         if ( x >= SDL_VideoSurface->w )
  194.             x = SDL_VideoSurface->w-1;
  195.  
  196.         if ( y < 0 )
  197.             y = 0;
  198.         else
  199.         if ( y >= SDL_VideoSurface->h )
  200.             y = SDL_VideoSurface->h-1;
  201.     } else {
  202.         move_mouse = 0;
  203.     }
  204.     if ( ! x )
  205.         x = SDL_MouseX;
  206.     if ( ! y )
  207.         y = SDL_MouseY;
  208.  
  209.     /* Figure out which event to perform */
  210.     buttonstate = SDL_ButtonState;
  211.     switch ( state ) {
  212.         case SDL_PRESSED:
  213.             event.type = SDL_MOUSEBUTTONDOWN;
  214.             buttonstate |= SDL_BUTTON(button);
  215.             break;
  216.         case SDL_RELEASED:
  217.             event.type = SDL_MOUSEBUTTONUP;
  218.             buttonstate &= ~SDL_BUTTON(button);
  219.             break;
  220.         default:
  221.             /* Invalid state -- bail */
  222.             return(0);
  223.     }
  224.  
  225.     /* Update internal mouse state */
  226.     SDL_ButtonState = buttonstate;
  227.     if ( move_mouse ) {
  228.         SDL_MouseX = x;
  229.         SDL_MouseY = y;
  230.         SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
  231.     }
  232.  
  233.     /* Post the event, if desired */
  234.     posted = 0;
  235.     if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
  236.         event.button.state = state;
  237.         event.button.button = button;
  238.         event.button.x = x;
  239.         event.button.y = y;
  240.         if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
  241.             posted = 1;
  242.             SDL_PushEvent(&event);
  243.         }
  244.     }
  245.     return(posted);
  246. }
  247.  
  248.